package com.dctp.common.utils;

import com.jfinal.kit.Kv;
import com.jfinal.plugin.activerecord.Record;

/**
 * 驼峰 ↔ 下划线 命名转换工具
 *
 * <pre>
 *   Record dbRec  = CamelSnakeUtil.camelToSnake(formRec);  // 保存数据库
 *   Kv      json  = CamelSnakeUtil.snakeToCamel(dbRecord); // 输出给前端
 *   String  snake = CamelSnakeUtil.toSnake("createTime");  // create_time
 *   String  camel = CamelSnakeUtil.toCamel("update_time"); // updateTime
 * </pre>
 */
public final class CamelSnakeUtil {

    private CamelSnakeUtil() {}   // 禁止实例化

    /** Record.camelCase → Record.snake_case */
    public static Record camelToSnake(Record in) {
        if (in == null) return null;
        Record out = new Record();
        for (String camel : in.getColumnNames()) {
            Object v = in.get(camel);
            if (v != null) out.set(toSnake(camel), v);
        }
        return out;
    }

    /** Record.snake_case → Kv.camelCase */
    public static Kv snakeToCamel(Record in) {
        if (in == null) return null;
        Kv kv = Kv.create();
        for (String snake : in.getColumnNames()) {
            kv.set(toCamel(snake), in.get(snake));
        }
        return kv;
    }

    /** snake_case → camelCase */
    public static String toCamel(String snake) {
        if (snake == null) return null;
        StringBuilder sb = new StringBuilder(snake.length());
        boolean up = false;
        for (char c : snake.toCharArray()) {
            if (c == '_') { up = true; continue; }
            sb.append(up ? Character.toUpperCase(c) : c);
            up = false;
        }
        return sb.toString();
    }

    /** camelCase → snake_case */
    public static String toSnake(String camel) {
        if (camel == null) return null;
        StringBuilder sb = new StringBuilder(camel.length() + 4);
        for (char c : camel.toCharArray()) {
            if (Character.isUpperCase(c)) {
                sb.append('_').append(Character.toLowerCase(c));
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }
}
